from octorotor.ui.Gauge import Gauge
from octorotor.ui.Graph import Graph
from octorotor.ui.MenuBar import MenuBar
from octorotor.ui.StartMenu import StartMenu
import wx.lib.newevent
from octorotor import Octorotor, OctorotorThread
from ValueSlider import *
import time
from octorotor.ui.UISettingRequest import UISettingRequest
from octorotor.ui.ValueSaver import ValueSaver
from JoystickValues import JoystickValues
import pygame

StartOctorotor, EVT_START_OCTOROTOR = wx.lib.newevent.NewEvent()
EndOctorotor, EVT_END_OCTOROTOR = wx.lib.newevent.NewEvent()

class MainWindow(wx.Frame):
    def __init__(self, parent):
 
        # A "-1" in the size parameter instructs wxWidgets to use the default size.
        # In this case, we select 200px width and the default height.
        wx.Frame.__init__(self, parent, title="Octorotor", size=(900, 900))
        
        self.ValueSaver = ValueSaver('values.txt')
        self.ValueSaver.readFromFile()
        
        self.menuBar = MenuBar()
        self.Graph = Graph(self)
        
        self.SetMenuBar(self.menuBar)
        
        self.topButtonbar = StartMenu(self)
        
        # Use some sizers to see layout options
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.topButtonbar, 0, wx.EXPAND)
        #self.sizer.Add(Graph(self), 1, wx.EXPAND)
        
        dataSizer = wx.BoxSizer(wx.HORIZONTAL)
        
        dataSizer.Add(self.Graph, 1, wx.EXPAND)
        dataSizer.Add(self.dataList(), 0, wx.EXPAND)
        
        self.sizer.Add(dataSizer, 1, wx.EXPAND)

        #Layout sizers
        self.SetSizer(self.sizer)
        self.SetAutoLayout(1)
        
        self.Show(True)
        
        self.ValueRequest = UISettingRequest( self.RollRange, self.YawRange )
        self.octorotorTimer = wx.Timer(self)
        self.lastOctorotorUpdate = 0
        self.StartTime = 0
        self.menuBar.setValueSaver(self.ValueSaver)
        
    def dataList(self):
        list = wx.BoxSizer(wx.VERTICAL)
        
        self.PitchGauge = Gauge(self, "Pitch", 'red')
        self.YawGauge = Gauge(self, "Yaw", 'green')
        self.RollGauge = Gauge(self, "Roll", 'blue')
        
        self.RollRange = ValueSlider(self, -1, "Roll Pitch Range", "RollPitchRange")
        self.YawRange = ValueSlider(self, -1, "Yaw Range", "YawRange")
        self.ControlAxis = JoystickValues(self)
        self.ControlAxis2 = JoystickValues(self)
        
        self.WriteCount =  wx.StaticText(self, -1, "Write count:", style=wx.ALIGN_RIGHT)
        
        self.YawGauge.oneLiner(True)
        self.RollRange.setValueSaver(self.ValueSaver)
        self.YawRange.setValueSaver(self.ValueSaver)
        
        list.Add(self.YawGauge, 0, wx.EXPAND)
        list.Add(self.PitchGauge, 0, wx.EXPAND)
        list.Add(self.RollGauge, 0, wx.EXPAND)
        list.Add(self.RollRange, 0, wx.EXPAND)
        list.Add(self.YawRange, 0, wx.EXPAND)
        list.Add(self.ControlAxis, 0, wx.EXPAND)
        list.Add(self.WriteCount, 0, wx.EXPAND)
        list.Add(self.ControlAxis2, 0, wx.EXPAND)
        
        return list
    
    def UpdateGauges(self, point):
        self.PitchGauge.SetAngle( point.Imu.p )
        self.YawGauge.SetAngle( point.Imu.y )
        self.RollGauge.SetAngle( point.Imu.r )
        
        
    def startOctorotor(self):
        comPort = self.menuBar.getComPort()
        baudRate = 57600
        
        print("Starting octorotor on " + str(comPort) + " with baudrate: " + str(baudRate))
        
        self.octoThread = OctorotorThread.OctoThread( comPort, baudRate )
        self.octoThread.start()
        
        self.octorotor =  self.octoThread.octorotor
        self.octorotor.SetValueRequest( self.ValueRequest )
            
        self.Bind(wx.EVT_TIMER, self.octorotorThink, self.octorotorTimer)
        
        self.octorotorTimer.Start(10) #Make the octorotor callback for data every 50 seconds
        self.StartTime = time.time()

        #create the event
        evt = StartOctorotor()
        #post the event
        wx.PostEvent(self, evt)
    
    def stopOctoorotor(self):        
        self.octorotorTimer.Stop()
        self.octoThread.endOctorotor()
        
        print("Stoping octorotor")
        
        #create the event
        evt = EndOctorotor()
        #post the event
        wx.PostEvent(self, evt)
        
    def octorotorThink(self, e):        
        octorotorDate = self.octorotor.LastUpdate
        
        if octorotorDate != self.lastOctorotorUpdate:
            dataPoints = self.octorotor.dataPoints
            
            if len(dataPoints) > 0:       
                self.UpdateGauges( dataPoints[-1] )
                self.Graph.GraphUpdate( dataPoints )
                self.ControlAxis.updateData( None )
                self.WriteCount.SetLabel("Write count: " + str(self.octorotor.writePerSeconds()) + "Hz")
                self.ControlAxis2.updateData( dataPoints[-1].returnData )
            
            self.lastOctorotorUpdate = octorotorDate
            
